#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
#include "KSADGlobals.hh"
#include "KSADPhysicsList.hh"
#include "KSADDetectorConstruction.hh"
#include "KSADPrimaryGeneratorAction.hh"
#include "KSADRunAction.hh"
#include "KSADEventAction.hh"
#include "KSADAnalyze.hh"
#include "Randomize.hh"
#include "TApplication.h"
#include <sstream>

void PrintUsage();

double crystalSize;
double timeRes;
G4String dataFilePath;
TH3D* globalH3;

int main(int argc, char** argv)
{
	crystalSize = 2.5*cm;
	timeRes = 0.4*ns;
	dataFilePath = "";

	G4String batchFile = "";

	for(int i = 1;i < argc;i++)
	{
		if(argv[i][0] == '-')
		{
			if(argv[i][1] == 'h')
			{
				PrintUsage();
				return 0;
			}
			else if(argv[i][1] == 'b')
			{
				i++;
				batchFile = argv[i];
			}
			else if(argv[i][1] == 'd')
			{
				i++;
				dataFilePath = argv[i];
			}
			else if(argv[i][1] == 'c')
			{
				i++;
				crystalSize = atof(argv[i]);
			}
			else if(argv[i][1] == 't')
			{
				i++;
				timeRes = atof(argv[i]);
			}
			else
			{
				PrintUsage();
				return 0;
			}
		}
		else
		{
			PrintUsage();
			return 0;
		}
	}

	G4long myseed = 336028;
	CLHEP::HepRandom::setTheSeed(myseed);

	int argcFake = 0;
	TApplication* app = new TApplication("app",&argcFake,argv);

	KSADAnalyze* analyze = new KSADAnalyze();

	// Make the run manager (runningMan)
	G4RunManager *runningMan = new G4RunManager();
	
	// Instanciate and initialize user initialization classes
	KSADDetectorConstruction *construction = new KSADDetectorConstruction();
	runningMan->SetUserInitialization(construction);

	G4VUserPhysicsList *physics = new KSADPhysicsList;
	runningMan->SetUserInitialization(physics);

	// Instanciate and initialize visualization manager
	G4VisManager *visMan = new G4VisExecutive();
	visMan->SetVerboseLevel(0);
	visMan->Initialize();

	// Instanciate and initialize user action classes
	KSADPrimaryGeneratorAction *generator = new KSADPrimaryGeneratorAction();
	runningMan->SetUserAction(generator);
	
	KSADRunAction *runAction = new KSADRunAction();
	runningMan->SetUserAction(runAction);

	KSADEventAction *eventAction = new KSADEventAction();
	runningMan->SetUserAction(eventAction);

	// Initialize run manager
	runningMan->Initialize();

	// Get pointer to UI manager and UI executive, then start session
	G4UImanager *UIman = G4UImanager::GetUIpointer();
	UIman->ApplyCommand("/run/verbose 0");
	UIman->ApplyCommand("/event/verbose 0");
	UIman->ApplyCommand("/tracking/verbose 0");
	if(batchFile != "")
	{
		UIman->ApplyCommand("/control/execute "+batchFile);
	}
	else
	{
		G4UIExecutive *ui = new G4UIExecutive(argcFake, argv);
		ui->SessionStart();
		delete ui;
	}


	delete visMan;
	delete runningMan;
	delete analyze;
	delete app;

	return 0;
}

void PrintUsage()
{
	G4cout << "Usage:\n\t-b BatchFilePath\n\t-d DataFilePath"
		<< "\n\t-c CrystalSize(cm)\n\t-t TimeResolution(ns)\n";
}
